﻿using MongoDB.Driver;
using System.Collections.Generic;
using System.Linq;
using up6.db.model;

namespace up6.db.database.up6.mongo
{
    /// <summary>
    /// 更新记录：
    ///     2022-12-13 完善delete,addBatch方法
    /// </summary>
    public class MongoFile : sql.SqlFile
    {
        /// <summary>
        /// 数据表：up6_files
        /// </summary>
        /// <returns></returns>
        public IMongoCollection<FileInf> table() {
            var db = MongoConfig.client().GetDatabase("up6");
            return db.GetCollection<FileInf>("up6_files");
        }

        public override FileInf read(string f_id) {
            var fs = this.table().Find(f => f.id == f_id).ToList();
            return fs.First();
        }

        public override FileInf exist_file(string md5)
        {
            if (string.IsNullOrEmpty(md5)) return null;
            var ret = this.table().Find(s => s.md5 == md5 && s.complete == true);
            if (ret.CountDocuments() > 0)
            {
                return ret.First();
            }
            return null;
        }

        public override void Add(ref FileInf f)
        {
            this.table().InsertOne(f);
        }

        public override void Clear()
        {
            this.table().DeleteMany(Builders<FileInf>.Filter.Empty);
        }


        /// <summary>
        /// 更新上传进度
        /// </summary>
        ///<param name="f_uid">用户ID</param>
        ///<param name="f_id">文件ID</param>
        ///<param name="f_pos">文件位置，大小可能超过2G，所以需要使用long保存</param>
        ///<param name="f_lenSvr">已上传长度，文件大小可能超过2G，所以需要使用long保存</param>
        ///<param name="f_perSvr">已上传百分比</param>
        public override bool process(string f_uid, string f_id, long offset, long f_lenSvr, string f_perSvr)
        {
            this.table().UpdateOne(Builders<FileInf>.Filter.Eq(f=>f.id, f_id),
                Builders<FileInf>.Update.Set(f=>f.blockOffset ,offset)
                .Set(f=>f.lenSvr,f_lenSvr)
                .Set(f=>f.perSvr,f_perSvr)
                );
            return true;
        }

        public override void complete(string id)
        {
            var fileSvr = this.table().Find(Builders<FileInf>.Filter.Eq(f => f.id, id)).FirstOrDefault();
            this.table().UpdateOne(Builders<FileInf>.Filter.Eq(f=>f.id, id),
                Builders<FileInf>.Update.Set(f => f.lenSvr,fileSvr.lenLoc)
                .Set(f => f.perSvr, "100%")
                .Set(f => f.complete, true)
                .Set(f => f.scaned, true)
                );
        }

        public override string uncmps(string uid) {
            var bf = Builders<FileInf>.Filter;
            var fl = bf.And( 
                bf.Eq(f=>f.uid, uid),
                bf.Eq(f=>f.complete, false));
            var fs = this.table().Find(fl).ToList();
            return Newtonsoft.Json.JsonConvert.SerializeObject(fs);
        }

        /// <summary>
        /// 删除一条数据，并不真正删除，只更新删除标识。
        /// </summary>
        /// <param name="f_uid"></param>
        /// <param name="f_id"></param>
        public override void Delete(string f_uid, string f_id)
        {
            var bf = Builders<FileInf>.Filter;
            var fl = bf.And(
                bf.Eq(f => f.uid, f_uid),
                bf.Eq(f => f.id, f_id));
            this.table().DeleteOne(fl);
        }

        public override void delete(string pathRel, string uid, string id)
        {
            var bf = Builders<FileInf>.Filter;
            var fl = bf.And(
                bf.Eq(f => f.pathRel, pathRel),
                bf.Eq(f => f.uid, uid),
                bf.Eq(f => f.id, id));
            this.table().UpdateMany(
                fl,
                Builders<FileInf>.Update.Set(f => f.deleted, true)
                );
        }

        public override void addBatch(List<FileInf> fs)
        {
            this.table().InsertMany(fs);
        }
    }
}